package com.example.network

import android.os.Environment
import com.alibaba.android.arouter.launcher.ARouter
import com.tencent.mmkv.MMKV
import okhttp3.Cache
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.security.SecureRandom
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.X509TrustManager


object HttpManager {

    fun getOkHttpClient(): OkHttpClient {
        return OkHttpClient.Builder().apply {
            connectTimeout(10, TimeUnit.SECONDS)
            readTimeout(10, TimeUnit.SECONDS)
            writeTimeout(10, TimeUnit.SECONDS)
            //设置拦截器
            addInterceptor(getTokenInterceptor())//Token拦截器
            addInterceptor(getNetCacheInterceptor())//网络缓存拦截器

            //设置日志拦截器并添加开关
            if (BuildConfig.isOpenLog){
                addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            }
            //配置Https请求的证书
            sslSocketFactory(sSlSocketFactory, trustManager)
            //设置网络缓存文件
            cache(getNetCacheFile() ?.let { Cache(it,20*102*1024) })

        }.build()
    }
    /**
     * 网络缓存拦截器
     * */
    private fun getNetCacheInterceptor(): Interceptor {
        return object : Interceptor{
            override fun intercept(chain: Interceptor.Chain): Response {
                var oldRequest = chain.request()
                var reqUrl =oldRequest.url
                //需要根据业务添加白名单
                if (!reqUrl.encodedPath.contains("user/login") ||
                    !reqUrl.encodedPath.contains("user/register")){
                    var newRequest = oldRequest.newBuilder().header("Cache-Control","max-age=3600").build()//缓存一小时
                    return chain.proceed(newRequest)
                }
                return chain.proceed(oldRequest)
            }
        }
    }
    /**
     *
     * Token拦截器
     * */
    private fun getTokenInterceptor(): Interceptor {
        return object : Interceptor{
            override fun intercept(chain: Interceptor.Chain): Response {
                var token = MMKV.defaultMMKV().decodeString("token")
                if (!token.isNullOrEmpty()){
                    var newRequest = chain.request().newBuilder().header("token",token).build()
                    var response = chain.proceed(newRequest)
                    //登录失败 需要跳转到登录页面
                    if (response.code == 403){
                        ARouter.getInstance().build("/activity/login").navigation()
                    }
                    return response
                }
                return chain.proceed(chain.request())
            }
        }
    }
    //获取一个sslSocketFactory
    private val sSlSocketFactory : SSLSocketFactory
        get() = try {
            val sslContext = SSLContext.getInstance("SSL")
            sslContext.init(null, arrayOf(trustManager), SecureRandom())
            sslContext.socketFactory
        } catch (e: Exception) {
            throw RuntimeException(e)
        }

    //获取一个忽略证书的X509TrustManager
    private val trustManager: X509TrustManager
        get() = object : X509TrustManager {
            override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {}
            override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {}
            override fun getAcceptedIssuers(): Array<X509Certificate> {
                return arrayOf()
            }
        }

    /**
     *
     * 获取网络缓存文件
     * */
    private fun getNetCacheFile() : File?{
        try {//获取外部Sd下目录
            val dirFile = Environment.getExternalStorageDirectory()
            if (dirFile.exists()){
                val cacheDirPath = "${dirFile.absolutePath}/netCacheFile"
                var cacheFile = File(cacheDirPath)
                if (cacheFile.exists()){
                    cacheFile= File(cacheDirPath)
                }
                return cacheFile
            }
            //获取内部存储目录
            return File("${Environment.getDownloadCacheDirectory().absolutePath}/netCacheFile")
        } catch (e: Exception) {
            return null
        }
    }


    //获取Retrofit
    fun getRetrofit() : Retrofit{
        var retrofit=Retrofit.Builder()
        with(retrofit){
            baseUrl(BuildConfig.BASE_URL)
            client(getOkHttpClient())
           // addConverterFactory(GsonConverterFactory.create()) //因为接口返回的数据太深类型不固定 不能统一转成JSON
        }
        return retrofit.build()
    }

    //获取接口实例对象
    fun <T> createApi(clazz: Class<*>): T {
        return getRetrofit().create(clazz) as T
    }


}